package com.demo.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.demo.springcloud.pojo.CommonResult;
import com.demo.springcloud.pojo.Payment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author chenyuan
 * @date 2020/12/23 9:50
 */
@RestController
public class RibbonController {
	@Value("${service-url.nacos-user-service}")
	private String SERVER_URL;

	@Autowired
	private RestTemplate restTemplate;

	@GetMapping(value = "/consumer/paymentSQL/{id}")
	// fallback 只负责业务异常
//    @SentinelResource(value = "fallback", fallback = "handlerFallBack")
	// blockHandler 只负责 Sentinel 控制台配置的熔断降级规则
//    @SentinelResource(value = "fallback", blockHandler = "blockHandler")
	@SentinelResource(value = "fallback", fallback = "handlerFallBack", blockHandler = "blockHandler"
			, exceptionsToIgnore = {IllegalArgumentException.class})
	public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
		CommonResult<Payment> result = restTemplate.getForObject(SERVER_URL + "/paymentSQL/" + id, CommonResult.class);

		// 异常捕捉
		if (id == 4) {
			throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
		} else if (result.getData() == null) {
			throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
		}
		return result;
	}

	/**
	 * FallBack 备选方案
	 */
	public CommonResult handlerFallBack(@PathVariable("id") Long id, Throwable e) {
		Payment payment = new Payment(id, "null");
		return new CommonResult<Payment>(444, "备选方案 —— handlerFallBack，异常内容" + e.getMessage(), payment);
	}

	/**
	 * blockHandler 备选方案
	 */
	public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) {
		Payment payment = new Payment(id, "null");
		return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水: blockException  " + blockException.getMessage(), payment);
	}
}
